{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Resource Estimation for Integer Factoring\n",
    "\n",
    "In this notebook we calculate resource estimates for a 2048-bit integer\n",
    "factoring application based on the implementation described in [[Quantum 5, 433\n",
    "(2021)](https://quantum-journal.org/papers/q-2021-04-15-433/)].  Our\n",
    "implementation incorporates all techniques described in the paper, except for\n",
    "carry runways.  As tolerated error budget, we choose $\\epsilon = 1/3$.\n",
    "\n",
    "For this application, we compute the physical resource estimates directly from\n",
    "precomputed logical resource estimates.  You can use this notebook as a blueprint to estimate the physical resources required of any application for which you already have computed logical estimates."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Getting started\n",
    "\n",
    "We import Python classes from `azure.quantum` to create a workspace and the resource estimator target."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from azure.quantum import Workspace\n",
    "from azure.quantum.target.microsoft import MicrosoftEstimator, QubitParams, QECScheme\n",
    "import qsharp"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We connect to the Azure Quantum workspace."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "workspace = Workspace (\n",
    "    resource_id = \"\",\n",
    "    location = \"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Extracting resource estimates from logical resource counts\n",
    "\n",
    "We create a Q# program that describes the algorithm in terms of precomputed logical resource estimates.  To this end, we are using the [AccountForEstimates](https://learn.microsoft.com/qsharp/api/qsharp/microsoft.quantum.resourceestimation.accountforestimates) operation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%%qsharp\n",
    "open Microsoft.Quantum.ResourceEstimation;\n",
    "\n",
    "operation FactoringFromLogicalCounts() : Unit {\n",
    "    use qubits = Qubit[12581];\n",
    "    \n",
    "    AccountForEstimates(\n",
    "        [TCount(12), RotationCount(12), RotationDepth(12),\n",
    "         CczCount(3731607428), MeasurementCount(1078154040)],\n",
    "        PSSPCLayout(), qubits);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Running experiments\n",
    "\n",
    "As configurations for the experiment we use all six pre-defined qubit\n",
    "parameters.  As pre-defined QEC scheme we are using `surface_code` with\n",
    "gate-based qubit parameters, and `floquet_code` with Majorana based qubit\n",
    "parameters.  For all experiments we assume an error budget of 1/3. We\n",
    "leverage the `make_params` function on the `estimator` by setting `num_items` to\n",
    "6 to create a batching job.  The `error_budget` is set globally for all items,\n",
    "where as names for `qubit_params` and `qec_scheme` are set individually for each\n",
    "item."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "estimator = MicrosoftEstimator(workspace)\n",
    "\n",
    "labels = [\"Gate-based µs, 10⁻³\", \"Gate-based µs, 10⁻⁴\", \"Gate-based ns, 10⁻³\", \"Gate-based ns, 10⁻⁴\", \"Majorana ns, 10⁻⁴\", \"Majorana ns, 10⁻⁶\"]\n",
    "\n",
    "params = estimator.make_params(num_items=6)\n",
    "params.error_budget = 0.333\n",
    "params.items[0].qubit_params.name = QubitParams.GATE_US_E3\n",
    "params.items[1].qubit_params.name = QubitParams.GATE_US_E4\n",
    "params.items[2].qubit_params.name = QubitParams.GATE_NS_E3\n",
    "params.items[3].qubit_params.name = QubitParams.GATE_NS_E4\n",
    "params.items[4].qubit_params.name = QubitParams.MAJ_NS_E4\n",
    "params.items[4].qec_scheme.name = QECScheme.FLOQUET_CODE\n",
    "params.items[5].qubit_params.name = QubitParams.MAJ_NS_E6\n",
    "params.items[5].qec_scheme.name = QECScheme.FLOQUET_CODE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next we are submitting the resource estimation job based on the Q# operation above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "job = estimator.submit(FactoringFromLogicalCounts, input_params=params)\n",
    "results = job.get_results()\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we are presenting the experimental results using a summary table."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "results.summary_data_frame(labels=labels)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The numbers in the table match the numbers in the paper [Assessing requirements\n",
    "for scaling quantum computers to real-world impact](https://aka.ms/AQ/RE/Paper).\n",
    "Feel free to use this table as a starting point for your own experiments.  For\n",
    "example, you can use other or customized qubit parameters."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
